﻿using System;
using System.Configuration;
using System.Linq;
using System.Web;
using System.Xml.Linq;
using System.Collections;
using System.Collections.Generic;

namespace Shut
{
	public class TocNode
	{
		#region Properties
		private string _Url;
		public string Url
		{
			get { return _Url; }
			set { _Url = value; }
		}
		private string _RealPath;
		public string RealPath
		{
			get { return _RealPath; }
			set { _RealPath = value; }
		}
		private string _Title;
		public string Title
		{
			get { return _Title; }
			set { _Title = value; }
		}
		private string _Key;
		public string Key
		{
			get { return _Key; }
			set { _Key = value; }
		}
		private string _Description;
		public string Description
		{
			get { return _Description; }
			set { _Description = value; }
		}
		private string _PageGroup;
		public string PageGroup
		{
			get { return _PageGroup; }
			set { _PageGroup = value; }
		}
		private bool _IsParent;
		public bool IsParent
		{
			get { return _IsParent; }
			set { _IsParent = value; }
		}
		private bool _Visible;
		public bool Visible
		{
			get { return _Visible; }
			set { _Visible = value; }
		}
		private string _ListClass;
		public string ListClass
		{
			get { return _ListClass; }
			set { _ListClass = value; }
		}
		private string _ItemClass;
		public string ItemClass
		{
			get { return _ItemClass; }
			set { _ItemClass = value; }
		}
		private string _ProviderName;
		public string ProviderName
		{
			get { return _ProviderName; }
			set { _ProviderName = value; }
		}
		private string _TranslateId;
		public string TranslateId
		{
			get { return _TranslateId; }
			set { _TranslateId = value; }
		}

		public static TocNode CurrentNode
		{
			get
			{
				if (CurrentSiteMapProvider.CurrentNode != null)
				{
					// find sitemap.currentnode, and return tocnode
					return Nodes.SingleOrDefault(p => p.Url == CurrentSiteMapProvider.CurrentNode.Url);
				}
				return new TocNode { Title = "", Url = "", Key = "", PageGroup = "" };
			}

		}

		#endregion


		public TocNode()
		{
			this._Title = "";
			this._Url = "~/404.aspx";
			this._RealPath = "~/404.aspx";
		}
		// nodes by provider 

		public static List<TocNode> FillSources()
		{

			List<TocNode> tocnodes = new List<TocNode>();
			SiteMapNodeCollection nodes = CurrentSiteMapProvider.RootNode.GetAllNodes();
			foreach (SiteMapNode n in nodes)
			{
				tocnodes.Add(LoadNode(n));
			}
			// homepage
			tocnodes.Add(LoadNode(CurrentSiteMapProvider.RootNode));

			return tocnodes;

		}
		// getchildren of node gets all nodes in nodes collection that have same parent guid
		// or make the siteroot here as a property and use children
		private static TocNode LoadNode(SiteMapNode n)
		{
			TocNode tn = new TocNode();
			// add guid
			// add parent guid
			tn.Title = n.Title;
			tn.Description = n.Description;
			tn.Url = n.Url;
			tn.Visible = (!String.IsNullOrEmpty(n["show"])) ? Convert.ToBoolean(n["show"]) : true;
			tn.RealPath = n["realPath"] ?? "";

			tn.IsParent = (!String.IsNullOrEmpty(n["pagegroup"])) ? true : false;
			tn.PageGroup = GetPageGroup(n);
			tn.ItemClass = n["liClass"] ?? "";
			tn.ListClass = n["ulClass"] ?? "";
			tn.ProviderName = ShutProvider;
			if (!string.IsNullOrEmpty(n["key"]))
			{
				tn.Key = n["key"];
			}
			else
			{
				tn.Key = "None";
			}
			//tn.TranslateId = n["t_id"];
			return tn;
		}
		private static object _SyncRoot = new object();

		private static List<TocNode> _Nodes;
		public static List<TocNode> Nodes
		{
			get
			{
				// get all nodes by provider name
				if (_Nodes == null)
				{
					_Nodes = new List<TocNode>();
				}
				List<TocNode> providerNodes = _Nodes.FindAll(f => f.ProviderName.Equals(ShutProvider));
				if (providerNodes.Count == 0)
				{
					lock (_SyncRoot)
					{
						// fill nodes with provider nodes
						providerNodes = FillSources();
						providerNodes.TrimExcess();
						// add providernodes to current nodes
						_Nodes.AddRange(providerNodes);
					}

				}
				return providerNodes;

			}
		}



		public static TocNode GetNode(string key)
		{
			return Nodes.Find(n => n.Key.Equals(key));
		}
		public static TocNode GetNode(string key, bool OrDefault)
		{
			TocNode tn = Nodes.Find(n => n.Key.Equals(key));
			if (OrDefault)
			{
				if (null == tn)
				{
					// return default empty node
					return new TocNode();
				}
			}
			return tn;
		}
		public static TocNode GetNode(string key, string DefaultUrl)
		{
			TocNode tn = Nodes.Find(n => n.Key.Equals(key));
			if (null == tn)
			{
				// return default empty node
				return tn = new TocNode
				{
					Url = DefaultUrl,
					RealPath = DefaultUrl,
					Title = "Moved!"
				};

			}

			return tn;
		}
		public static TocNode GetNodeByUrl(string url)
		{
			return Nodes.Find(n => n.Url.Equals(url));
		}

		public static List<TocNode> GetNodesByGroup(string PageGroupName)
		{
			return Nodes.FindAll(n => n.PageGroup.Equals(PageGroupName));

		}

		public static SiteMapProvider CurrentSiteMapProvider
		{
			get
			{
				return SiteMap.Providers[SiteSettings.Instance.SiteMapName];

			}
		}

		public static string ShutProvider
		{
			get
			{
				return CurrentSiteMapProvider.Name;
			}
		}
		public static string GetPageGroup(SiteMapNode snode)
		{
			// look into parents until u hit a wall return nothing
			if (snode == null) return "";
			if (!String.IsNullOrEmpty(snode["pageGroup"]))
			{
				return snode["pageGroup"];
			}
			else
			{
				if (snode.ParentNode != null)
				{
					string pg = GetPageGroup(snode.ParentNode);
					return pg;
				}
				else
				{
					return "";
				}
			}
		}

	}
}